# coding=utf-8

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
from models import models
from models.settings import Menu
from utils.enums import Struct
from utils.htmlutils import setXmlType, setXhtmlType
from xml.dom import minidom
import logging


class MainPage(webapp.RequestHandler):

    def __init__(self):
        self.struct = Struct()
        self.struct.user = users.get_current_user()
        self.struct.account = models.get_account(self.struct.user)


    def _init_get(self):
        self.template_file = 'templates/main.xhtml'

        self.struct.logo = 'Welcome to the main page'

        self.struct.href_login = users.create_login_url('/')
        self.struct.href_logout = users.create_logout_url('/')

        self.struct.menu = Menu

        self.struct.title = 'YooHOo, ' + (self.struct.user
                                          and self.struct.user.nickname()
                                          or '%username%') + ' !'

    def get(self):
        #setXhtmlType(self.response)
        self._init_get()
        self.response.out.write(template.render(self.template_file, self.struct._compile()))


class Handler(webapp.RequestHandler):
    def __init__(self):
        self.struct = Struct()

    def post(self):
        setXmlType(self.response)
        self._post()

    def _post(self):
        pass;


class WordHandler(Handler):
    def _post(self):
        action = self.request.get('action')
        if None == action:
            self.response.set_status(400, 'Bad Request')
            return

        if(action == 'delete'):
            id = self.request.get('id')
            models.remove_word(id)
            return
        elif(action == 'update'):
            id = self.request.get('id')
            logging.info('####!DEBUG! id ' + id)
            field = self.request.get('field')
            logging.info('####!DEBUG! field ' + field)
            value = self.request.get('value')
            logging.info('####!DEBUG! value ' + value)
            word = models.get_word(id)
            if(field == 'eng'):
                word.eng = value
            elif(field == 'rus'):
                word.rus = value
            elif(field == 'engtr'):
                word.eng_tr = value
            elif(field == 'part'):
                word.part = value
            elif(field == 'pop'):
                word.pop = int(value)
            word.put()
            return


    def _clean(self):
        words = models.Word.gql("WHERE rus = ''")
        def deleteWord(a):
            a.delete()
        map(deleteWord, words)

    def _fill(self):
        name = 'templates/words.xml'
        logging.info('####!DEBUG! test2 ' + name)
        xmldoc = minidom.parse(name)
        listWords = xmldoc.getElementsByTagName('w:p')

        partOfSpeech = ['adv', 'prep', 'verb', 'a', 'v', 'n']

        for tagWord in listWords:
            wordParts = tagWord.getElementsByTagName('w:r')

            #logging.info('####!DEBUG! test2 ' + str(wordParts.length))

            if(wordParts.length > 5):

                try:
                    word = models.Word()
                    word.eng = self._getText(wordParts[0])

                    for wordPart in wordParts[2:-2]:
                        font = self._getFont(wordPart)
                        text = self._getText(wordPart)
                        if(text == '-' or text == ']'):
                            continue
                        elif(text in partOfSpeech):
                            word.part = text
                        elif(font == 'PhoneticTM'):
                            word.eng_tr += text
                        else:
                            word.rus += text

                    try:
                        word.pop = int(self._getText(wordParts[-2]).lstrip('.'))
                    except ValueError:
                        word.pop = -1

                    word.put()

                    logging.info('####!DEBUG!  ' + str(word))

                except UnicodeEncodeError:
                    logging.info('####!DEBUG!  UnicodeEncodeError')





    def _getText(self, tag):
        wt = tag.getElementsByTagName('w:t')[0]
        return wt.firstChild.data.rstrip().lstrip()

    def _getFont(self, tag):
        wrFonts = tag.getElementsByTagName('w:rFonts')
        return (wrFonts.length > 0 and wrFonts[0].getAttribute('w:ascii').rstrip().lstrip()) or ''




class MenuHandler(Handler):
    def _post(self):
        logging.info('init ' + str(self.__class__))
        menuid = None
        try:
            menuid = int(self.request.get('menuid', '0'))
        except ValueError:
            self.response.set_status(400, 'Bad Request')
            return

        if not menuid in xrange(len(Menu)):
            self.response.set_status(400, 'Bad Request')
            return

        self.struct.user = users.get_current_user()
        if Menu[menuid] == "Settings":
            if(self.struct.user is None):
                self.response.out.write(template.render('templates/resp/forbidden.xml', ''))
                return
            self.response.out.write(template.render('templates/resp/settings.xml', self.struct._compile()))
            return
        elif Menu[menuid] == "Notes":
            if(self.struct.user is None):
                self.response.out.write(template.render('templates/resp/forbidden.xml', ''))
                return

            self.struct.notes = models.get_notes(self.struct.user)
            self.response.out.write(template.render('templates/resp/notes.xml', self.struct._compile()))
            return
        elif Menu[menuid] == "Words":
            self.struct.words = models.get_words()

            self.response.out.write(template.render('templates/resp/words.xml', self.struct._compile()))
            return

        self.response.set_status(400, 'Bad Request')

class NoteHandler(Handler):
    def __init__(self):
        super(NoteHandler, self).__init__();
        logging.info('init ' + str(self.__class__))
        self.note_template = 'templates/resp/note.xml'

    def _post(self):
        self.user = users.get_current_user()
        if None == self.user:
            self.response.set_status(403, 'Forbidden')
            return

        action = self.request.get('action')
        if None == action:
            self.response.set_status(400, 'Bad Request')
            return


        if action == 'new':
            self._new()
        elif action == 'edit':
            self._edit()
        elif action == 'apply':
            self._apply()
        elif action == 'remove':
            self._remove()
        elif action == 'cancel':
            self._cancel()


    def _new(self):
        self.struct.note = models.create_note(self.user, 'Title of the new note', 'Sample')
        self.struct.note.edit = True
        self.response.out.write(template.render(self.note_template, self.struct._compile()))

    def _edit(self):
        id = self.request.get('id')
        if not id:
            self.response.set_status(400, 'Bad Request')
            return
        self.struct.note = models.get_note(id)
        if not self.struct.note:
            self.response.set_status(400, 'Bad Request')
            return
        self.struct.note.edit = True
        self.response.out.write(template.render(self.note_template, self.struct._compile()))

    def _remove(self):
        id = self.request.get('id')
        if not id:
            self.response.set_status(400, 'Bad Request')
            return

        models.remove_note(id)


    def _cancel(self):
        id = self.request.get('id')

        if not id:
            self.response.set_status(400, 'Bad Request')
            return

        self.struct.note = models.get_note(id)
        if not self.struct.note:
            self.response.set_status(400, 'Bad Request')
            return
        self.response.out.write(template.render(self.note_template, self.struct._compile()))

    def _apply(self):
        id = self.request.get('id')
        title = self.request.get('title')[:500]
        text = self.request.get('note')[:500]


        logging.info('text: ' + text)

        if not title or not text or not id:
            self.response.set_status(400, 'Bad Request')
            return

        self.struct.note = models.get_note(id)
        if not self.struct.note:
            self.response.set_status(400, 'Bad Request')
            return

        self.struct.note.title = title
        self.struct.note.note = text
        self.struct.note.put()
        self.response.out.write(template.render(self.note_template, self.struct._compile()))








